import 'package:analyzer/dart/element/element.dart';
import 'package:froom_generator/value_object/type_converter.dart' as froomvalue;
import 'package:froom_generator/misc/type_utils.dart';
import 'dart:async';
import 'package:build/build.dart';
import 'package:fall_data_base/fall_data_base.dart';
import 'package:fall_gen_base/fall_gen_base.dart';

class TcUtil {
  static Set<froomvalue.TypeConverter> getTypeConverters(
      final Set<ClassElement> tcs, final froomvalue.TypeConverterScope scope) {
    return tcs.map((tc) => toElement(tc, scope)).toSet();
  }

  static froomvalue.TypeConverter toElement(
      ClassElement tc, froomvalue.TypeConverterScope scope) {
    // 检查类是否继承自TypeConverter
    final supertype = tc.supertype;
    if (supertype == null) {
      throw ArgumentError(
          'Only classes that inherit from TypeConverter can be used as type converters. '
          'Make sure to use a class that inherits from TypeConverter.');
    }

    // 获取泛型参数
    final typeArguments = supertype.typeArguments;
    if (typeArguments.length < 2) {
      throw ArgumentError(
          'TypeConverter must have two type arguments: <FieldType, DatabaseType>');
    }

    final fieldType = typeArguments[0];
    final databaseType = typeArguments[1];
    if (!databaseType.isDefaultSqlType) {
      throw ArgumentError(
          'Type converters have to convert to a database-compatible type. '
          'Make the class convert to either int, double, String, bool or Uint8List.');
    }

    // 创建并返回TypeConverter对象
    return froomvalue.TypeConverter(
      tc.displayName, // 类名
      fieldType, // 字段类型
      databaseType, // 数据库类型
      scope, // 作用域
    );
  }

  /// 检查ClassElement是否继承自TypeConverter
  ///
  /// 这是一个便利方法，专门用于检查TypeConverter子类
  static bool isTypeConverter(ClassElement element) {
    return ClassUtil.isSubclassOf(element, 'TypeConverter');
  }

  /// 加载TypeConverter子类的便利方法
  ///
  /// [buildStep] 构建步骤
  /// [typeConverterPath] TypeConverter文件路径
  static Future<Set<ClassElement>> loadTypeConverters(
      BuildStep buildStep, String typeConverterPath) async {
    return ClassUtil.loadSubclasses(
        buildStep, typeConverterPath, 'TypeConverter');
  }

  /// 获取数据库名称
  ///
  /// 从元素的@DB注解中提取数据库名称，如果没有注解则返回默认值
  /// [element] 需要检查的元素
  /// 返回数据库名称，默认为 DB.Default
  static String getDbName(Element element) {
    LogUtil.d('检查元素 ${element.name} 的DB注解');

    try {
      String dbName = 'Default';
      return AnnoUtil.getAnnotationValue(element, DB, 'name', dbName);
    } catch (e) {
      LogUtil.d('获取DB名称失败,${e.toString()}');
      return 'Default';
    }
  }
}
